package bin_tree.leetcode;

/**
 * @author yuisama
 * @date 2023/03/28 19:15
 * 根据前序和中序遍历结果来还原整颗二叉树
 **/
public class Num105_PreOrderAndInOrder {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        return buildTreeHelper(preorder,inorder,0,inorder.length - 1);
    }

    /**
     * 借助前序遍历，在中序遍历结果集[left...right]上还原二叉树
     * @param preorder
     * @param inorder
     * @param left
     * @param right
     * @return
     */
    // 当前处理到前序遍历的哪个结点了
    int index = 0;
    private TreeNode buildTreeHelper(int[] preorder, int[] inorder, int left, int right) {
        // base case
        if (index == preorder.length) {
            // 所有节点已经处理完毕
            return null;
        }
        if (left > right) {
            // 当前中序遍历的[left..right] 区间中没有元素
            return null;
        }
        // 1.先从前序遍历的结果集中找到根节点
        int val = preorder[index];
        index ++;
        TreeNode root = new TreeNode(val);
        // 2.再从中序遍历中找到当前树根的索引pos
        int pos = find(inorder,val);
        // 3.此时根据中序遍历的结果位置
        root.left = buildTreeHelper(preorder,inorder,left,pos - 1);
        root.right = buildTreeHelper(preorder,inorder,pos + 1,right);
        return root;
    }
    // 在当前中序遍历的结果集[left..right]找到待查找元素val的索引
    private int find(int[] inorder, int val) {
        for (int i = 0;i < inorder.length;i++) {
            if(inorder[i] == val) {
                return i;
            }
        }
        return -1;
    }
}